package org.hackystat.devcathlon.engine.profile;

import static org.junit.Assert.*;

import java.util.List;

import org.hackystat.devcathlon.engine.user.User;
import org.hackystat.devcathlon.engine.user.UserManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * Test ProfileManager class.
 * 
 * @author Anthony Du
 */
public class TestProfileManager {

  /** Common declarations. */
  private static final String firstName = "Anthony";
  private static final String lastName = "Du";
  private static final String email = "anthony@gmail.com";
  private static final String email2 = "anthony@gmail.net";
  private static final String gender = "m";
  private static final String location = "Hawaii";
  private static final String contact = "808";
  private static final String bioInfo = "Bio";
  private static final String avatar = "Avatar";
  private static final String password = email;
  private User user1, user2;

  /**
   * This sets up a default user. A User must exist first before having a Profile.
   */
  @Before
  public void setUp() {
    user1 = UserManager.getInstance().addUser(firstName, lastName, email, password);
    user2 = UserManager.getInstance().addUser(firstName, lastName, email2, password);
  }

  /**
   * This removes the previously initialized User.
   */
  @After
  public void cleanUp() {
    UserManager.getInstance().deleteUser(email);
    UserManager.getInstance().deleteUser(email2);
  }

  /**
   * Test adding/loading/deleting of a Profile.
   */
  @Test
  public void testProfileManager() {
    // create a Profile.
    Profile profile = ProfileManager.getInstance().addProfile(user1, gender, location,
            contact, bioInfo, avatar);
    // load the previously created Profile.
    Profile selectedProfile = ProfileManager.getInstance().getProfile(email);
    // test to see if the user added is the same as the user selected.
    assertNotSame("should be the same", selectedProfile, profile);
    // clean up
    ProfileManager.getInstance().deleteProfile(email);
    // test to see if the profile deleted is truly gone.
    assertNull("should be null", ProfileManager.getInstance().getProfile(email));
  }

  /**
   * Test getUsers.
   */
  @Test
  public void testGetProfiles() {
    // Test to see if the list of users is empty.
    List<?> profilesList = ProfileManager.getInstance().getProfiles();
    assertTrue("users list should be empty", profilesList.isEmpty());
    Profile profile1 = ProfileManager.getInstance().addProfile(user1, gender, location,
            contact, bioInfo, avatar);
    Profile profile2 = ProfileManager.getInstance().addProfile(user2, gender, location,
            contact, bioInfo, avatar);
    // Test to see if only two profiles reside in the query.
    profilesList = ProfileManager.getInstance().getProfiles();
    int numProfiles = profilesList.size();
    assertEquals("should have 2 profiles", 2, numProfiles);
    // Test if the profiles were the original ones added.
    Profile selectedProfile = ProfileManager.getInstance().getProfile(email);
    assertEquals("should be profile 1", profile1.getUser(), selectedProfile.getUser());
    selectedProfile = ProfileManager.getInstance().getProfile(email2);
    assertEquals("should be profile 2", profile2.getUser(), selectedProfile.getUser());
    // Test profile email
    assertEquals("should have 1 email", 1, selectedProfile.getEmailAddresses().size());
    // Cleanup.
    ProfileManager.getInstance().deleteProfile(email);
    ProfileManager.getInstance().deleteProfile(email2);
    profilesList = ProfileManager.getInstance().getProfiles();
    assertTrue("profiles list should be empty", profilesList.isEmpty());
  }
  
  /**
   * Test profile update.
   */
  @Test
  public void testUpdateProfile() {
    // create a Profile.
    Profile profile = ProfileManager.getInstance().addProfile(user1, gender, location,
            contact, bioInfo, avatar);
    // update profile
    Profile updatedProfile = profile;
    String otherContact = "832";
    updatedProfile.setContact(otherContact);
    ProfileManager.getInstance().updateProfile(updatedProfile);
    // test to see if they are the same record
    assertSame("should be the same profile", updatedProfile, profile);
    // test to see if record has in fact changed
    assertNotSame("should not be the same email", contact, updatedProfile.getContact());
  }
  
  /**
   * Test profile - user association.
   */
  @Test
  public void testProfileUser() {
    Profile profile = ProfileManager.getInstance().addProfile(user1, gender, location,
        contact, bioInfo, avatar);
    // test to see if the profile user is the same as the associated
    assertEquals("should be the same user", user1, profile.getUser());
    // test to see if the user profile is the same as the associated
    assertEquals("should be the same profile", profile, user1.getProfile());
    // test retrieving information from profile user (by association)
    assertEquals("should be the same email", email, profile.getUser().getEmail());
  }
}
